package thread;

import graphics.Principal;

import java.util.ArrayList;
import java.util.concurrent.Semaphore;

public class Carro extends Thread {
	private String nome;
	private int tempoTravessia;
	private int tempoPermanencia;
	private String sentido;
	private static int contadorPonte;
	private int contadorSul;
	private static Semaphore ponte = new Semaphore(1);
	private static Semaphore norte = new Semaphore(10);
	private static Semaphore sul = new Semaphore(10);
	private static Semaphore mutex = new Semaphore(1);
	public boolean morra = false;
	private Principal principal;
	public static Carro [] listaPonte = new Carro [10];
	
	public Carro(String nome, int tempoTravessia, String sentido,
			int contadorNorte, int contadorSul, Principal principal,
			int tempoPermanencia) {
		super();
		this.nome = nome;
		this.tempoTravessia = tempoTravessia * 1000;
		this.sentido = sentido;
		this.contadorSul = contadorSul;
		this.principal = principal;
		this.tempoPermanencia = tempoPermanencia * 1000;
	}

	public Carro() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * @return the nome
	 */
	public String getNome() {
		return nome;
	}

	/**
	 * @param nome
	 *            the nome to set
	 */
	public void setNome(String nome) {
		this.nome = nome;
	}

	/**
	 * @return the tempoTravessia
	 */
	public int getTempoTravessia() {
		return tempoTravessia;
	}

	/**
	 * @param tempoTravessia
	 *            the tempoTravessia to set
	 */
	public void setTempoTravessia(int tempoTravessia) {
		this.tempoTravessia = tempoTravessia;
	}

	/**
	 * @return the sentido
	 */
	public String getSentido() {
		return sentido;
	}

	/**
	 * @param sentido
	 *            the sentido to set
	 */
	public void setSentido(String sentido) {
		this.sentido = sentido;
	}

	@Override
	public void run() {
		while (!morra) {
			try {
				principal.cuidandoNaVida(tempoPermanencia, sentido);
				mutex.acquire();
				principal.log.setText(nome + " quer a ponte \n"
						+ principal.log.getText());
				long tempoAux = System.currentTimeMillis();
				while ((1500 + tempoAux) - System.currentTimeMillis() > 0) {
					
				}
				if (this.sentido.equals("norte")) {
					principal.listaN += 1;
					if (principal.listaN == 1) {
						principal.getCarroNorte().setVisible(true);
					}else{
//						principal.getCarroNorte2().setText(""+principal.listaN);
//						principal.getCarroNorte2().setVisible(true);
					}
				} else {
					principal.listaS += 1;
					if (principal.listaS == 1 ) {
						principal.getCarroSul().setVisible(true);
					}else{
//						principal.getCarroSul2().setText(""+principal.listaS);
//						principal.getCarroSul2().setVisible(true);
					}
				}
				
				tempoAux = System.currentTimeMillis();
				while ((600 + tempoAux) - System.currentTimeMillis() > 0) {
					
				}
				
				mutex.release();

				if (this.sentido.equals("norte")) {
					if (principal.listaN == 1 || contadorPonte == 0) {
						ponte.acquire(1);
					}
				} else {
					if (principal.listaS == 1 || contadorPonte == 0) {
						ponte.acquire(1);
					}
				}
				

				if (this.sentido.equals("norte")) {
					mutex.acquire();
					listaPonte [contadorPonte] = (this);
					contadorPonte++;
					if(principal.listaN -1<= 0){
						principal.getCarroNorte().setVisible(false);
					}
					mutex.release();
				} else {
					mutex.acquire();
					listaPonte [contadorPonte] = new Carro();
					listaPonte [contadorPonte] = (this);
					contadorPonte++;
					if(principal.listaS -1 <= 0){
						principal.getCarroSul().setVisible(false);
					}
					mutex.release();
				}
				
				
				int i = 0;
				long tempoIni = System.currentTimeMillis();
				while ((tempoTravessia + tempoIni) - System.currentTimeMillis() > 0) {
					if (i == 0) {
						principal.log.setText(nome
								+ " está na ponte indo para " + this.sentido
								+ " \n" + principal.log.getText());
						tempoAux = System.currentTimeMillis();
						while ((1500 + tempoAux) - System.currentTimeMillis() > 0) {
							
						}
//						atravessarPonte();
						i++;
					}
					if (sentido.equals("norte")) {
						if(principal.listaN <= 0){
							principal.getCarroNorte().setVisible(false);
						}
						if (!principal.getCarroNortePonte().isVisible()) {
							principal.getCarroNortePonte().setVisible(true);
						}
						if (System.currentTimeMillis() % 5 == 0) {
							principal.getCarroNortePonte().setBounds(600, 250, 32, 64);
						} else {
							principal.getCarroNortePonte().setBounds(600, 255, 32, 64);
						}
					} else {
						if(principal.listaS <= 0){
							principal.getCarroSul().setVisible(false);
						}
						if (!principal.getCarroSulPonte().isVisible()) {
							principal.getCarroSulPonte().setVisible(true);
						}
						if (System.currentTimeMillis() % 2 == 0) {
							principal.getCarroSulPonte().setBounds(600, 250, 33, 66);
						} else {
							principal.getCarroSulPonte().setBounds(600, 255, 33, 66);
						}
					}
				}
				
				if(contadorPonte > 1 && listaPonte[contadorPonte-1].getTempoTravessia() < listaPonte[contadorPonte-2].getTempoTravessia()){
					while(true){
						mutex.acquire();
						if(listaPonte[0].getNome().equals(this.nome)){
							mutex.release();break;
						}
						mutex.release();
					}
				}
				
				mutex.acquire();
				if(contadorPonte > 1){
					ordenarLista(listaPonte);
				}
				mutex.release();
				if (this.sentido.equals("norte")) {
					mutex.acquire();
					principal.listaN -= 1;
					contadorPonte--;
					
					mutex.release();
				} else {
					mutex.acquire();
					principal.listaS -= 1;
					contadorPonte--;
					
					mutex.release();
				}
				
				
				if(sentido.equals("norte") && contadorPonte == 0){
					principal.getCarroNortePonte().setVisible(false);
				}else if(contadorPonte == 0){
					principal.getCarroSulPonte().setVisible(false);
				}
				System.out.println("Na ponte: "+contadorPonte);
				mutex.acquire();
				principal.log.setText(this.nome + " sai da ponte \n"
						+ principal.log.getText());
				tempoAux = System.currentTimeMillis();
				while ((1500 + tempoAux) - System.currentTimeMillis() > 0) {
					
				}
				if (this.sentido.equals("norte")) {
					if (contadorPonte == 0) {
						tempoAux = System.currentTimeMillis();
						while ((1500 + tempoAux) - System.currentTimeMillis() > 0) {
							
						}
						principal.log.setText(this.nome + " libera a ponte \n"
								+ principal.log.getText());
						ponte.release(1);
					}
				} else {
					if (contadorPonte == 0) {
						tempoAux = System.currentTimeMillis();
						while ((1500 + tempoAux) - System.currentTimeMillis() > 0) {
							
						}
						principal.log.setText(this.nome + " libera a ponte \n"
								+ principal.log.getText());
						ponte.release(1);
					}
				}
				cuidarNaVida();
				mutex.release();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}

	private void ordenarLista(Carro[] listaPonte) {
		for(int i=1; i < listaPonte.length; i++){
			listaPonte[i-1] = listaPonte[i];
		}
	}

	private void atravessarPonte() throws InterruptedException {
		mutex.acquire();
		if (this.sentido.equals("norte")) {
			principal.setListaS(principal.getListaS() + 1);
		} else {
			principal.setListaN(principal.getListaN() + 1);
		}
		mutex.release();
	}

	private void cuidarNaVida() throws InterruptedException {
		principal.log.setText(this.getNome() + " está cuidando na vida \n"
				+ principal.log.getText());
		if (this.sentido.equals("norte")) {
			this.sentido = "sul";
		} else {
			this.sentido = "norte";
		}
//		principal.cuidandoNaVida(tempoPermanencia, sentido);
	}
}